﻿using System.Collections.Specialized;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using DBFile.Core.Configuration;
using DBFile.Core.Extensions;
using DBFile.Providers;
using Microsoft.VisualStudio.TestTools.UnitTesting;


namespace DBFile.MSTest
{
    [TestClass]
    public class DBFileTest
    {
        public DBFileTest()
        {
    
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion
        [TestInitialize()]
        public void Initialize()
        {
            string tempDir = "E:\\Temp";
            string tempTextFileName = Path.Combine(tempDir, "test.xml");

            TestContext.Properties.Add("tempDir", tempDir);
            TestContext.Properties.Add("tempTextFileName", tempTextFileName);

            NameValueCollection configValue = new NameValueCollection();
            configValue.Add("name", "FileSystemProvider");
            configValue.Add("type", "DBFile.Providers.FileSystemProvider, DBFile.FileSystemProvider");
            configValue.Add("repositoryPath", "E:\\Temp");

            DBFile.Providers.FileSystemProvider provider = new FileSystemProvider();
            provider.Initialize("FileSystemProvider", configValue);

            if (DBFileProvider.Providers.Count == 0)
            {
                DBFileProvider.Providers.Add(provider);
                DBFileProvider.Providers.DefaultProviderName = provider.Name;
            }
            TestContext.Properties.Add("Provider", provider);
        }

        [TestCleanup()]
        public void Cleanup()
        {
            string tempTextFileName = testContextInstance.Properties["tempTextFileName"].ToString();
            
            File.Delete(tempTextFileName);            
        }

        [TestMethod]
        public void XmlDocExtension()
        {
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            
            string xmlText = "<root><ele1>text</ele1></root>";
            CreateTextFile(DBFileProvider.Instance(), tempTextFileName, xmlText);
                       
            XmlDocument doc = new XmlDocument();
            doc.LoadFromDB(tempTextFileName);

            Assert.AreEqual(1, doc.ChildNodes.Count);
            Assert.AreEqual("root", doc.DocumentElement.Name);
            Assert.AreEqual("ele1", doc.DocumentElement.ChildNodes[0].Name);
            Assert.AreEqual("text", doc.DocumentElement.ChildNodes[0].InnerText);            
        }

        [TestMethod]
        public void XDocExtension()
        {
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            var xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
                new XElement("root",
                    new XElement("ele1", new XAttribute("att1", "text"))));           
            
            CreateTextFile(DBFileProvider.Instance(), tempTextFileName, xml.ToString());

            var doc = new XDocument().LoadFromDB(tempTextFileName);

            Assert.IsNotNull(doc);
            Assert.AreEqual("root", doc.Root.Name.LocalName);

            XElement ele = doc.Root.Element("ele1");
            Assert.IsNotNull(ele);
        }

        [TestMethod]
        public void XDocSaveExtension()
        {
            var xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
                new XElement("root",
                    new XElement("ele1", new XAttribute("att1", "text"))));

            xml.SaveToDB("dbtest.xml");
                        
            var doc = new XDocument().LoadFromDB("dbtest.xml");

            Assert.IsNotNull(doc);
            Assert.AreEqual("root", doc.Root.Name.LocalName);

            XElement ele = doc.Root.Element("ele1");
            Assert.IsNotNull(ele);
        }

        [TestMethod]
        public void XElementExtension()
        {
            string tempTextFileName = TestContext.Properties["tempTextFileName"].ToString();
            var xml = new XElement("root2",
                        new XElement("ele2", new XAttribute("att2", "text")));

            CreateTextFile(DBFileProvider.Instance(), tempTextFileName, xml.ToString());

            var doc = new XElement("root").LoadFromDB(tempTextFileName);

            Assert.IsNotNull(doc);
            Assert.AreEqual("root2", doc.Name.LocalName);

            XElement ele = doc.Element("ele2");
            Assert.IsNotNull(ele);
        }

        [TestMethod]
        public void XElementSaveExtension()
        {
            var xml = new XElement("root2",
                      new XElement("ele2", new XAttribute("att2", "text")));

            xml.SaveToDB("dbeletest.xml");

            var doc = new XDocument().LoadFromDB("dbeletest.xml");

            Assert.IsNotNull(doc);
            Assert.AreEqual("root2", doc.Root.Name.LocalName);

            XElement ele = doc.Root.Element("ele2");
            Assert.IsNotNull(ele);
        }
        

        private void CreateTextFile(DBFileProvider provider, string filename, string content)
        {
            Assert.IsFalse(provider.Exists(filename));
            
            File.WriteAllText(filename, content);

            Assert.IsTrue(provider.Exists(filename));
        }

        
    }
}
